package com.question.java.date7;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * DateUtil类
 * 
 */
public class DateUtil {

	public static final String Y_M = "yyyy-MM";
	public static final String Y_M_D = "yyyy-MM-dd";
	public static final String Y_M_D_HM = "yyyy-MM-dd HH:mm";
	public static final String Y_M_D_HMS = "yyyy-MM-dd HH:mm:ss";
	public static final String YMD = "yyyyMMdd";
	public static final String YMDHM = "yyyyMMddHHmm";
	public static final String YMDHMS = "yyyyMMddHHmmss";
	public static final String ymd = "yyyy/MM/dd";
	public static final String ymd_HM = "yyyy/MM/dd HH:mm";
	public static final String ymd_HMS = "yyyy/MM/dd HH:mm:ss";
	public static final String numchars = "012345678987654abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkj";
	/**
	 * 智能转换日期
	 * 
	 * @param date
	 * @return
	 */
	public static String smartFormat(Date date) {
		String dateStr = null;
		if (date == null) {
			dateStr = "";
		} else {
			try {
				dateStr = formatDate(date, Y_M_D_HMS);
				// 时分秒
				if (dateStr.endsWith(" 00:00:00")) {
					dateStr = dateStr.substring(0, 10);
				}
				// 时分
				else if (dateStr.endsWith("00:00")) {
					dateStr = dateStr.substring(0, 16);
				}
				// 秒
				else if (dateStr.endsWith(":00")) {
					dateStr = dateStr.substring(0, 16);
				}
			} catch (Exception ex) {
				throw new IllegalArgumentException("转换日期失败: " + ex.getMessage(), ex);
			}
		}
		return dateStr;
	}

	/**
	 * 智能转换日期
	 * 
	 * @param text
	 * @return
	 */
	public static Date smartFormat(String text) {
		Date date = null;
		try {
			if (text == null || text.length() == 0) {
				date = null;
			} else if (text.length() == 8) {
				date = formatStringToDate(text, YMD);
			} else if (text.length() == 10) {
				date = formatStringToDate(text, Y_M_D);
			} else if (text.length() == 13) {
				date = new Date(Long.parseLong(text));
			} else if (text.length() == 14) {
				date = formatStringToDate(text, YMDHMS);
			} else if (text.length() == 16) {
				date = formatStringToDate(text, Y_M_D_HM);
			} else if (text.length() == 19) {
				date = formatStringToDate(text, Y_M_D_HMS);
			} else {
				throw new IllegalArgumentException("日期长度不符合要求!");
			}
		} catch (Exception e) {
			throw new IllegalArgumentException("日期转换失败!");
		}
		return date;
	}

	/**
	 * 获取当前日期
	 * 
	 * @param format
	 * @return
	 */
	public static String getNow(String format) {
		return formatDate(new Date(), format);
	}

	/**
	 * 封装一个获取（当前日期Date类型）的方法
	 * 
	 * @return 当前日期Date类型
	 */
	public static Date getNowDate() {
		return new Date();
	}

	/**
	 * 获取当前日期
	 * 
	 * @param format
	 * @return
	 * @throws Exception
	 */
	public static String getNow() {
		try {
			return formatDate(new Date(), Y_M_D_HMS);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 格式化日期格式
	 * 
	 * @param argDate
	 * @param argFormat
	 * @return 格式化后的日期字符串
	 */
	public static String formatDate(Date argDate, String argFormat) {
		if (argDate == null) {
			throw new RuntimeException("参数[日期]不能为空!");
		}
		if (argFormat == null || "".equals(argFormat)) {
			argFormat = Y_M_D;
		}
		SimpleDateFormat sdfFrom = new SimpleDateFormat(argFormat);
		return sdfFrom.format(argDate).toString();
	}

	/**
	 * 把字符串格式化成日期
	 * 
	 * @param argDateStr
	 * @param argFormat
	 * @return
	 */
	public static Date formatStringToDate(String argDateStr, String argFormat) {
		if (argDateStr == null || argDateStr.trim().length() < 1) {
			throw new RuntimeException("参数[日期]不能为空!");
		}
		String strFormat = argFormat;
		if (argFormat == null || "".equals(argFormat)) {
			strFormat = Y_M_D;
			if (argDateStr.length() > 16) {
				strFormat = Y_M_D_HMS;
			} else if (argDateStr.length() > 10) {
				strFormat = Y_M_D_HM;
			}
		}
		SimpleDateFormat sdfFormat = new SimpleDateFormat(strFormat);
		// 严格模式
		sdfFormat.setLenient(false);
		try {
			return sdfFormat.parse(argDateStr.replaceAll("/", "-"));
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获得当前日期的前两个月
	 * 
	 * @Description TODO
	 * @date 2016年4月14日
	 * @author lingy
	 * @return Date
	 * @throws
	 */
	public static Date getBefroeMonthByCurrentDate(int monthNum) {
		monthNum = -monthNum;
		Date date = computeCalendarByDateAndMonthnum(monthNum, 1);
		return date;
	}

	/**
	 * @param <T>
	 *            获得当前日期的后两个月
	 * @Description TODO
	 * @date 2016年4月14日
	 * @author lingy
	 * @return Date
	 * @throws
	 */
	public static Date getAfterMonthByCurrentDate(int monthNum) {
		monthNum = monthNum + 1;
		Date date = computeCalendarByDateAndMonthnum(monthNum, 0);
		return date;
	}

	/**
	 * 
	 * @Description TODO
	 * @date 2016年4月14日
	 * @author lingy
	 * @param monthNum
	 * @param compute
	 * @return Date
	 * @throws
	 */
	private static Date computeCalendarByDateAndMonthnum(int monthNum, int compute) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, monthNum);
		cal.set(Calendar.DAY_OF_MONTH, compute);
		Date date = cal.getTime();
		return date;
	}

	/**
	 * 比较时间相差分钟数
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long compareDayandDay(String date1, String date2) {
		Date newdate1 = null;
		Date newdate2 = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			newdate1 = sdf.parse(date1);
			newdate2 = sdf.parse(date2);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		long temp = newdate1.getTime() - newdate2.getTime(); // 相差毫秒数
		// long hours = temp / 1000 / 3600; //相差小时数
		long temp2 = temp / (1000 * 60);
		// long mins = temp2 / 1000 / 60; //相差分钟数
		// System.out.println("date2 与 date 相差" + hours + "小时"+ mins + "分钟");
		return temp2;
	}

	/**
	 * 比较时间相差秒
	 *
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long compareDayandDaySecond(String date1, String date2) {
		Date newdate1 = null;
		Date newdate2 = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			newdate1 = sdf.parse(date1);
			newdate2 = sdf.parse(date2);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		long temp = newdate1.getTime() - newdate2.getTime(); // 相差毫秒数
		// long hours = temp / 1000 / 3600; //相差小时数
		long temp2 = temp /1000;
		// long mins = temp2 / 1000 / 60; //相差分钟数
		// System.out.println("date2 与 date 相差" + hours + "小时"+ mins + "分钟");
		return temp2;
	}


	/**
	 * 取得某日期的前一天
	 */
	public static String getBeforOneDay(String formart, Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat(formart);
		Calendar cales = Calendar.getInstance();
		cales.setTime(date);
		cales.add(Calendar.DATE, -1);
		return formatter.format(cales.getTime());
	}
	
	/**
	 * 取得某日期的前一月
	 */
	public static String getBeforOneMonth(String formart, Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat(formart);
		Calendar cales = Calendar.getInstance();
		cales.setTime(date);
		cales.add(Calendar.MONTH, -1);
		return formatter.format(cales.getTime());
	}

	/**
	 * 取得某日期的后一天
	 */
	public static String getAfterOneDay(String formart, Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat(formart);
		Calendar cales = Calendar.getInstance();
		cales.setTime(date);
		cales.add(Calendar.DATE, 1);
		return formatter.format(cales.getTime());
	}
	
	/**
	 * 取得某日期之前或之后的某一天
	 */
	public static Date getAfterOrBeforeDay(Date date, int days) {
		Calendar cales = Calendar.getInstance();
		cales.setTime(date);
		cales.add(Calendar.DATE, days);
		return cales.getTime();
	}

	/**
	 * 取得某日期之前或之后的某一天String型
	 */
	public static String getAfterOrBeforeDayToString(String currdate, int days) {
		SimpleDateFormat formatter = new SimpleDateFormat(Y_M_D);
		Date dd;
		Calendar cales = Calendar.getInstance();
		try {
			dd = formatter.parse(currdate);
			cales.setTime(dd);
			cales.add(Calendar.DATE, days);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return formatter.format(cales.getTime());
	}
	
	/**
	 * 取得某日期的后一月
	 */
	public static String getAfterOneMonth(String formart, Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat(formart);
		Calendar cales = Calendar.getInstance();
		cales.setTime(date);
		cales.add(Calendar.MONTH, 1);
		return formatter.format(cales.getTime());
	}

	/**
	 * 获取两个日期间隔多少天
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static int getDayDiff(Date d1, Date d2) {
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(d1);
		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(d2);
		long l = cal1.getTimeInMillis() - cal2.getTimeInMillis();
		return new Long(l / (1000 * 60 * 60 * 24)).intValue();
	}
	
	/**
	 * 获取hours小时之前之后的数据
	 * 
	 * @return
	 */
	public static Date headDate(String date , int hours) {
	    Calendar cal = Calendar.getInstance();
	    try {
			cal.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(date));
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    cal.add(Calendar.HOUR_OF_DAY, hours);
	    return cal.getTime();
	}
	
	/** 
    * 按天分割一段日期 
    * @param start 开始时间 
    * @param end 结束时间 
    * @return 
    */  
   public static List<String> getIntervalTimeList(Date startDate, Date endDate){
       List<String> list = new ArrayList<>();
       while(startDate.getTime()<=endDate.getTime()){  
    	   list.add(formatDate(startDate,Y_M_D));  
           Calendar calendar = Calendar.getInstance();
           calendar.setTime(startDate);  
           calendar.add(Calendar.DAY_OF_YEAR,1);
           if(calendar.getTime().getTime()>endDate.getTime()){  
               if(!startDate.equals(endDate)){  
                  list.add(formatDate(endDate,Y_M_D));  
               }  
               startDate = calendar.getTime();  
           }else{  
               startDate = calendar.getTime();  
           }  
  
       }  
       return list;  
   }  
   
   
     public static int daysBetween(String smdate, Date bdate){
	     SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
	     Calendar cal = Calendar.getInstance();
	     long time1 = 0;
	     long time2 = 0;
	      
	     try{
	       cal.setTime(sdf.parse(smdate));  
	       time1 = cal.getTimeInMillis();  
	       cal.setTime(bdate); 
	       time2 = cal.getTimeInMillis(); 
	     }catch(Exception e){
	       e.printStackTrace();
	     }
	     long between_days=(time2-time1)/(1000*3600*24); 
	        
	    return Integer.parseInt(String.valueOf(between_days));
	   }
     
     
     public static String generateRadomNumChar(){
	    String result = "";
	    char[] m = numchars.toCharArray();  
        for (int j = 0; j < 16; j++) {  
            char c = m[(int) (Math.random() * 37)];
            // 保证六位随机数之间没有重复的  
            if (result.contains(String.valueOf(c))) {
                j--;  
                continue;  
            }  
            result = result + c;  
        }  
	    return result;   
	 }
   
     
     public static boolean isBelong(String begin, String end){
	    SimpleDateFormat df = new SimpleDateFormat("HH:mm");//设置日期格式
	    Date now =null;
	    Date beginTime = null;
	    Date endTime = null;
	    try {
	        now = df.parse(df.format(new Date()));
	        beginTime = df.parse(begin);
	        endTime = df.parse(end);
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	    Boolean flag = belongCalendar(now, beginTime, endTime);
	    return flag;
    }
     
     
     /**
      * 判断时间是否在时间段内
      * @param nowTime
      * @param beginTime
      * @param endTime
      * @return
      */
     public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
         Calendar date = Calendar.getInstance();
         date.setTime(nowTime);

         Calendar begin = Calendar.getInstance();
         begin.setTime(beginTime);

         Calendar end = Calendar.getInstance();
         end.setTime(endTime);

         if (date.after(begin) && date.before(end)) {
             return true;
         } else {
             return false;
         }
     }

	/**
	 * 计算两个日期相差月份
	 * @param date1
	 * @param date2
	 * @return
	 * @throws ParseException
	 */
	public static int getMonthSpace(Date date1, Date date2) {
		int result = 0;
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(date1);
		c2.setTime(date2);
		result = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
		return result == 0 ? 1 : Math.abs(result);
	}


     

	public static String getNextNow(String format) {
		SimpleDateFormat sdfFrom = new SimpleDateFormat(format);
		Date date = new Date();
		Calendar calendar   =   new GregorianCalendar();
		calendar.setTime(date); 
		calendar.add(calendar.YEAR, 1);
		date = calendar.getTime();
		return sdfFrom.format(date).toString();	    
	}

	public static int getMonthDiffer(Date date1, Date date2){
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(date1);
		c2.setTime(date2);
		if(c1.getTimeInMillis() < c2.getTimeInMillis()) return 0;
		int year1 = c1.get(Calendar.YEAR);
		int year2 = c2.get(Calendar.YEAR);
		int month1 = c1.get(Calendar.MONTH);
		int month2 = c2.get(Calendar.MONTH);
		int day1 = c1.get(Calendar.DAY_OF_MONTH);
		int day2 = c2.get(Calendar.DAY_OF_MONTH);
		// 获取年的差值 假设 d1 = 2015-8-16  d2 = 2011-9-30
		int yearInterval = year1 - year2;
		// 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
		if(month1 < month2) yearInterval --;
		// 获取月数差值
		int monthInterval =  (month1 + 12) - month2  ;
		//if(day1 < day2) monthInterval --;
		monthInterval %= 12;
		return yearInterval * 12 + monthInterval;
	}

	public static String getPassDate(Date updateDate, String format) {
		SimpleDateFormat sdfFrom = new SimpleDateFormat(format);
		String dateStr=sdfFrom.format(updateDate);
		return dateStr;
	}
	
	public static int differentDays(Date date1, Date date2)
    {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
       int day1= cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);
        
        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if(year1 != year2)
        {
            int timeDistance = 0 ;
            for(int i = year1 ; i < year2 ; i ++)
            {
                if(i%4==0 && i%100!=0 || i%400==0)        
                {
                    timeDistance += 366;
                }
                else 
                {
                    timeDistance += 365;
                }
            }
            
            return timeDistance + (day2-day1) ;
        }
        else
        {
            System.out.println("判断day2 - day1 : " + (day2-day1));
            return day2-day1;
        }
    }


	/**
	 * 日期相加减
	 * @param time
	 *             时间字符串 yyyy-MM-dd HH:mm:ss
	 * @param num
	 *             加的数，-num就是减去
	 * @return
	 *             减去相应的数量的年的日期
	 * @throws ParseException
	 */
	public static Date yearAddNum(Date time, Integer num) {
		//SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//Date date = format.parse(time);

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		calendar.add(Calendar.YEAR, num);
		Date newTime = calendar.getTime();
		return newTime;
	}

	/**
	 *
	 * @param time
	 *           时间
	 * @param num
	 *           加的数，-num就是减去
	 * @return
	 *          减去相应的数量的月份的日期
	 * @throws ParseException Date
	 */
	public static Date monthPlus(Date time, Integer num){
		//SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//Date date = format.parse(time);

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		calendar.add(Calendar.MONTH, num);
		Date newTime = calendar.getTime();
		return newTime;
	}

	/**
	 *
	 * @param time
	 *           时间
	 * @param num
	 *           加的数，-num就是减去
	 * @return
	 *          减去相应的数量的天的日期
	 * @throws ParseException Date
	 */
	public static Date dayPlus(Date time, Integer num){
		//SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//Date date = format.parse(time);

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		calendar.add(Calendar.DAY_OF_MONTH, num);
		Date newTime = calendar.getTime();
		return newTime;
	}

}